package com.erps.CommonUtils;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;

public class ImageParser {
	private static List swatches = null;

	private static List swatcheValues = null;

	private byte[][] targetColors;

	// ------------------------------------------------------------ Test main
	// method
	public static void main(String[] args) {
		String[] files = new String[10];
		String[] values = new String[10];
		for (int i = 0; i < files.length; i++) {
			files[i] = "D:\\workspace\\SZXClientAPP\\res\\" + i + ".jpg";
			values[i] = String.valueOf(i);
		}

		ImageParser parse = new ImageParser(files, values);
		long startime = System.currentTimeMillis();
		try {
			System.out
					.println(parse
							.parseValue("D:\\workspace\\SZXClientAPP\\res\\ValidateNum"));
			long sincetime = System.currentTimeMillis();
			System.out.println("��ʱ�� = " + (sincetime - startime));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// ------------------------------------------------------------ Constructors

	public ImageParser(String[] files, String[] values) {
		// ֻ��������һ�μ���
		if (swatches == null && swatcheValues == null) {
			int fileslength = files.length;
			int valueslength = values.length;
			if (fileslength != valueslength) {
				System.out.println("���ļ�������ֵ��ƥ�䣡���������ã�");
				return;
			}
			swatches = new ArrayList(fileslength);
			swatcheValues = new ArrayList(valueslength);
			int i = 0;
			try {
				for (; i < files.length; i++) {
					swatches.add(imageToMatrix(files[i]));
					swatcheValues.add(i, values[i]);
				}
			} catch (Exception e) {
				System.out.println(files[i] + " can not be parsed");
				e.printStackTrace();
			}
		}
	}

	public ImageParser() {
		super();
		if (swatches == null || swatcheValues == null) {
			System.out.println("��δ����������������");
		}
	}

	/**
	 * ����ͼƬ��ֵ
	 * 
	 * @param parseFilePath
	 *            ���ͼƬ·��
	 * @return �����ַ�
	 * @throws Exception
	 */
	public String parseValue(String parseFilePath) throws Exception {
		StringBuffer result = new StringBuffer();
		targetColors = imageToMatrix(parseFilePath);
		// printMatrix(targetColors);
		int height = targetColors.length;
		int targetWidth = targetColors[0].length;

		int width = 0;
		Iterator it = swatches.iterator();
		while (it.hasNext()) {
			byte[][] bytes = (byte[][]) it.next();
			int templen = bytes[0].length;
			if (templen > width)
				width = templen;
		}
		// System.out.println("MaxWidth = " + width);
		// System.out.println("MaxHeight = " + height);
		int xTag = 0;
		while ((xTag + width) < targetWidth) {
			cout: {
				Iterator itx = swatches.iterator();
				int i = 0;
				while (itx.hasNext()) {
					byte[][] bytes = (byte[][]) itx.next();
					byte[][] temp = splitMatrix(targetColors, xTag, 0, width,
							height);
					// System.out.println(i++);
					if (isMatrixInBigMatrix(bytes, temp)) {
						xTag += width;
						// System.out.println("new maxtrix: ");
						// printMatrix(temp);

						result.append(swatcheValues.get(i));
						break cout;
					}
					i++;
				}
				xTag++;
			}
		}
		return result.toString();
	}

	private static final boolean isMatrixInBigMatrix(byte[][] source,
			byte[][] bigMatrix) {
		if (source == bigMatrix)
			return true;
		if (source == null || bigMatrix == null)
			return false;

		if (source.length > bigMatrix.length)
			return false;

		try {
			for (int i = 0; i < source.length; i++) {
				if (source[i].length > bigMatrix[i].length)
					return false;
			}
		} catch (ArrayIndexOutOfBoundsException e) {
			return false;
		}

		int height = source.length;
		int width = source[0].length;
		int x = 0, y = 0;
		int i = 0, j = 0;
		int count = 0;

		int comparecount = height * width;

		for (; i < bigMatrix.length - height + 1; i++) {
			for (j = 0; j < bigMatrix[i].length - width + 1; j++) {
				cout: {
					x = 0;
					count = 0;
					for (int k = i; k < height + i; k++) {
						y = 0;
						for (int l = j; l < width + j; l++) {
							// System.out.println("bytes[" + x + "][" + y + "]"
							// + " = " + source[x][y] + ", " + "other["
							// + k + "][" + l + "] = " + bigMatrix[k][l]);
							if ((source[x][y] & bigMatrix[k][l]) == source[x][y]) {
								count++;
							} else
								break cout;
							y++;
						}
						x++;
					}
					// System.out.println("count = " + count);
					if (count == comparecount)
						return true;
				}
			}
		}
		return false;
	}

	private static final byte[][] splitMatrix(byte[][] source, int x, int y,
			int width, int height) {
		byte[][] resultbytes = new byte[height][width];
		for (int i = y, k = 0; i < height + y; i++, k++) {
			for (int j = x, l = 0; j < width + x; j++, l++) {

				resultbytes[k][l] = source[i][j];
				// System.out.println("source[" + i + "][" + j + "]" + " = " +
				// source[i][j] + ", " + "resultbytes["
				// + k + "][" + l + "] = " + resultbytes[k][l]);
			}

		}
		return resultbytes;
	}

	private byte[][] imageToMatrix(String filePath) throws Exception {
		// �����ļ�
		Image image = ImageIO.read(new File(filePath));
		int w = image.getWidth(null);
		int h = image.getHeight(null);
		BufferedImage src = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		src.getGraphics().drawImage(image, 0, 0, null);

		byte[][] colors = new byte[h][w];

		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				int rgb = src.getRGB(j, i);
				// ���ؽ��лҶȴ���
				String sRed = Integer.toHexString(rgb).substring(2, 4);
				String sGreen = Integer.toHexString(rgb).substring(4, 6);
				String sBlank = Integer.toHexString(rgb).substring(6, 8);
				long ired = Math
						.round((Integer.parseInt(sRed, 16) * 0.3 + 0.5d));
				long igreen = Math
						.round((Integer.parseInt(sGreen, 16) * 0.59 + 0.5d));
				long iblank = Math
						.round((Integer.parseInt(sBlank, 16) * 0.11 + 0.5d));
				long al = ired + igreen + iblank;

				// if (al > 127)
				// System.out.print(" " + " ");
				// else
				// System.out.print(" " + "1");
				// System.out.print(" " + (tempint > = maxint ? 0 : 1));
				// System.out.println("tempInt = " + tempint);

				/* ��ͼ��ת����0,1 */
				// �˴���ֵ���Խ����޸ĳ�������Ҫ�жϵ�ֵ
				colors[i][j] = (byte) (al > 127 ? 0 : 1);
			}
			// System.out.println();
		}

		return colors;
	}

	private static final void printMatrix(byte[][] matrix) {
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix[i].length; j++) {
				if (matrix[i][j] == 0)
					System.out.print(" ");
				else
					System.out.print(" 1");
			}
			System.out.println();
		}
	}
}
